<script lang="ts" setup>
import { onMounted, provide, ref } from 'vue'
import type { ProfileItem, RoleItem, UserItem } from './dto/get-user.dto'
import {
  addUserService,
  delUserService,
  editUserService,
  getUserListService
} from '@/api/user'
import * as bootstrap from 'bootstrap'
import { AxiosError } from 'axios'
import DelModal from '@/components/modal/DelModal.vue'
import addEditModal from '@/components/modal/AddEditModal.vue'
import type { FormItem, formValueItem } from '@/components/Form.vue'
// 定义用户列表
const userList = ref([] as UserItem[])
// 临时单个用户数据
const tempItem = ref({} as UserItem)
// 定义用户查询参数(分页/筛选)
const userpages = ref({
  // 页码
  page: 1,
  // 每页条数
  limit: 7
})
// 总页数
const totalPages = ref()
// 页码按钮数组
const pageBtns = ref([] as number[])
// 禁用上/下一页
const prevbtn = ref(true)
const nextbtn = ref(false)
// 设置总页数，渲染页码按钮，禁用上/下一页
const setTotalPages = async () => {
  // 判断有多少页
  // 未分页数据
  const res = await getUserListService()
  // console.log('🚀 ~ setTotalPages ~ res:', res)
  // 临时数据
  const tempPages = res.length / userpages.value.limit
  // 如果tempPages是整数则返回本身，不是整数向下取整+1
  // 总页数
  totalPages.value = Number.isInteger(tempPages) ? tempPages : Math.floor(tempPages + 1)

  // 渲染页码按钮
  pageBtns.value = [] //每次清空数组
  for (let i = 1; i <= totalPages.value; i++) {
    // 用于向数组的末尾添加一个或多个元素，并返回修改后的数组
    pageBtns.value.push(i)
  }

  //上下页禁用逻辑
  if (userpages.value.page === 1) {
    prevbtn.value = true
    nextbtn.value = false
  } else if (userpages.value.page === totalPages.value) {
    prevbtn.value = false
    nextbtn.value = true
  } else {
    prevbtn.value = false
    nextbtn.value = false
  }
}

// 通过api获取用户列表
const getUserLists = async () => {
  // 设置总页数
  setTotalPages()
  const res = await getUserListService(userpages.value)
  if (res && res.length > 0) {
    userList.value = res
  }
}
// 表单数据初始值
const formValue = ref({
  username: '',
  password: '',
  profile: {
    gender: 0,
    phone: '',
    address: ''
  } as ProfileItem,
  roles: [] as RoleItem[]
} as UserItem)
// 数据初始化函数
// const initialUser = () => {
//   formValue.value = {
//     username: '',
//     password: '',
//     profile: {
//       gender: 0,
//       phone: '',
//       address: ''
//     } as ProfileItem,
//     roles: [] as RoleItem[]
//   } as UserItem
// }

// 模态框表单字段
const formSchema: FormItem[] = [
  {
    field: '用户名：',
    type: 'input',
    prop: 'username',
    value: '',
    attr: {
      placeholder: '请输入用户名'
    }
  },
  {
    field: '密码：',
    type: 'input',
    prop: 'password',
    value: '',
    attr: {
      placeholder: '请输入密码'
    }
  },
  {
    field: '角色：',
    type: 'checkbox',
    prop: 'roles',
    value: [],
    children: [
      {
        field: '管理员',
        value: 1
      },
      {
        field: '普通用户',
        value: 2
      },
      {
        field: '测试用户',
        value: 3
      }
    ]
  },
  {
    field: '性别：',
    type: 'radio',
    prop: 'gender',
    value: 0,
    children: [
      { field: '男', value: 1 },
      { field: '女', value: 2 }
    ]
  },
  {
    field: '头像：',
    type: 'input',
    prop: 'phone',
    value: '',
    attr: {
      placeholder: '请粘贴头像路径'
    }
  },
  {
    field: '地址：',
    type: 'input',
    prop: 'address',
    value: '',
    attr: {
      placeholder: '请输入用户地址'
    }
  }
]
// 将formSchema表单传递给form组件
provide('formSchema', formSchema)
// 控制删除模态框的显示隐藏：delShow=>传递给子
const delShow = ref(false)
// 编辑模态框控制
const editRefS = ref()
onMounted(() => {
  // 初始化用户列表
  getUserLists()
})

const msg = ref('编辑')

// 3.控制模态框
const openModal = (type: string, item?: UserItem) => {
  if (type === 'del') {
    tempItem.value = item || ({} as UserItem)
    delShow.value = true
  } else if (type === 'add') {
    // 数据初始化
    editRefS.value.clearFormValue()
    msg.value = '新增'
    // 显示编辑模态框
    editRefS.value.show()
  } else if (type === 'edit') {
    // 将获取到的item赋值给tempItem
    // bug1：form表单变,内容跟着变=> 进行深拷贝
    const strItem = JSON.stringify(item || ({} as UserItem))
    tempItem.value = JSON.parse(strItem)
    // bug2：显示不出角色=> 因为复选框v-model需要的是数字数组，而提供的是{id,name}数组
    const roleArrId: number[] = tempItem.value.roles.map((o) => o.id)
    tempItem.value.roles = roleArrId as unknown as RoleItem[]
    // 打开之前，填充数据到form表单里
    msg.value = '编辑'
    // 数据初始化
    editRefS.value.clearFormValue()
    // 显示编辑模态框
    editRefS.value.show()
  }
}
// 将打开编辑之后的tempItem传递给form,进行数据填充
provide('tempItem', tempItem)
// 新增服务
const editSubmit = async (val: formValueItem) => {
  // 一一映射到相对应的数据
  formValue.value.username = val.username
  formValue.value.password = val.password
  formValue.value.roles = val.roles
  formValue.value.profile.address = val.address
  formValue.value.profile.gender = val.gender
  formValue.value.profile.phone = val.phone
  // 新增和编辑逻辑
  if (msg.value === '新增') {
    try {
      await addUserService(formValue.value)
      // 刷新总页数
      await setTotalPages()
      // 新增的时候需要回到最后一页：当前页等于总页数
      await (userpages.value.page = totalPages.value)
      // 刷新用户列表
      await getUserLists()
      editRefS.value.clearFormValue()
      editRefS.value.hide()
    } catch (error: unknown) {
      console.error('新增用户失败：', error)
      const err = error as { message: string; response: { data: { message: string } } }
      alert(`新增用户失败：${err?.message || err?.response?.data?.message || '未知错误'}`)
    }
  } else if (msg.value === '编辑') {
    try {
      // 这里的headers的AUthorization对应的是它的id,应付一下
      const res = await editUserService(formValue.value, tempItem.value.id)
      console.log(res.message)
      // 刷新用户列表
      getUserLists()
      // 数据初始化
      editRefS.value.clearFormValue()
      editRefS.value.hide()
    } catch (error) {
      console.error('编辑用户失败：', error)
      const err = error as { message: string; response: { data: { message: string } } }
      alert(`编辑用户失败：${err?.message || err?.response?.data?.message || '未知错误'}`)
    }
  }
}
// 删除服务
const delSubmit = async () => {
  if (tempItem.value) {
    const res = await delUserService(tempItem.value.id)
    getUserLists()
    if (res.message === '该用户已删除') {
      delShow.value = false
      // 总页数
      const ress = await getUserListService()
      //删除的时候发现: 数据长度/偏移量为整数时，执行向上一页，否则
      const tempPages = ress.length / userpages.value.limit
      if (Number.isInteger(tempPages)) {
        previousPage()
      }
    }
  }
}
//bug1: form表单变内容跟着变 bug2：显示不出角色 bug3：删除不了
// bug4:数据只会显示12条，而后台只会显示10条：因为后台我设置了默认：const take = limit || 0
// 做分页和头部筛选
// 分页
// 上一页
const previousPage = () => {
  if (userpages.value.page > 1) {
    userpages.value.page -= 1
    getUserLists()
  } else {
    return console.log('没有上一页')
  }
}
// 下一页
const nextPage = async () => {
  setTotalPages()
  if (userpages.value.page < totalPages.value) {
    userpages.value.page += 1
    getUserLists()
  } else {
    return console.log('没有下一页')
  }
}
// 设置页码按钮
const pageBtn = (page: number) => {
  // page是v-for的数组项，
  userpages.value.page = page
  // 为了使禁用按钮同步以及分页数据初始化
  getUserLists()
}
</script>
<template>
  <div>
    <div class="mb-3">
      <button type="button" class="btn btn-primary" @click="openModal('add')">
        <i class="fas fa-plus"></i>新增
      </button>
    </div>
    <!-- 表格 -->
    <table class="table table-bordered table-hover table-striped fs-6">
      <thead>
        <tr>
          <th scope="col">序号</th>
          <th scope="col" style="width: 10%">用户名</th>
          <th scope="col" style="width: 25%">角色</th>
          <th scope="col">性别</th>
          <th scope="col" style="width: 15%">头像</th>
          <th scope="col" style="width: 15%">地址</th>
          <th scope="col">操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item, index) in userList" :key="item.id">
          <!-- 序号 = (当前页-1) * 偏移量 + index + 1 -->
          <th scope="row">{{ (userpages.page - 1) * userpages.limit + index + 1 }}</th>
          <td>{{ item.username }}</td>
          <td>{{ item.roles.map((o) => o.name).join('、') }}</td>
          <td>
            {{
              item.profile &&
              (item.profile.gender === 1 ? '男' : item.profile.gender === 2 ? '女' : '')
            }}
          </td>
          <td>{{ item.profile && item.profile.phone }}</td>
          <td>{{ item.profile && item.profile.address }}</td>
          <td>
            <button
              type="button"
              class="btn btn-secondary px-3 me-2"
              @click="openModal('edit', item)"
            >
              <i class="fa-regular fa-pen-to-square me-2"></i>编辑</button
            ><button
              type="button"
              class="btn btn-danger px-3"
              @click="openModal('del', item)"
            >
              <i class="fa-solid fa-trash me-2"></i>删除
            </button>
          </td>
        </tr>
      </tbody>
    </table>
    <!-- 模态弹框 新增/编辑/删除-->
    <!-- add/editModal -->
    <addEditModal ref="editRefS" :msg="msg" @editSubmit="editSubmit"></addEditModal>

    <!-- delModal -->
    <DelModal v-model="delShow" @delSubmit="delSubmit"></DelModal>

    <!-- <div
      class="modal fade fs-5"
      id="delModal"
      ref="delRef"
      tabindex="-1"
      aria-labelledby="delModal"
      aria-hidden="true"
    >
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title fs-5" id="delModalLabel">删除</h5>
            <button
              type="button"
              class="btn-close"
              data-bs-dismiss="modal"
              aria-label="Close"
            ></button>
          </div>
          <div class="modal-body fs-5">确定删除该条记录吗？</div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
              取消
            </button>
            <button type="button" class="btn btn-primary" @click="delSubmit()">
              确定
            </button>
          </div>
        </div>
      </div>
    </div> -->
    <!-- 分页 -->
    <nav aria-label="Page navigation example ">
      <ul class="pagination d-flex justify-content-end">
        <li class="page-item" :class="{ disabled: prevbtn }" @click="previousPage()">
          <a class="page-link" href="#" ref="pageItems" tabindex="-1" aria-disabled="true"
            >上一页</a
          >
        </li>
        <li
          class="page-item"
          :class="{ active: userpages.page === page }"
          v-for="page in pageBtns"
          :key="page"
          @click="pageBtn(page)"
        >
          <a class="page-link" href="#">{{ page }}</a>
        </li>
        <!-- <li class="page-item"><a class="page-link" href="#">2</a></li>
        <li class="page-item"><a class="page-link" href="#">3</a></li> -->
        <li class="page-item" :class="{ disabled: nextbtn }" @click="nextPage()">
          <a class="page-link" href="#">下一页</a>
        </li>
      </ul>
    </nav>
  </div>
</template>
<style scoped></style>
